/*
 * @version: 1.0
 * @Author: zhl
 * @Date: 2021-09-06 14:46:16
 * @LastEditors: zhl
 * @LastEditTime: 2021-09-30 09:02:52
 * @Description: file content
 */
#ifndef __DLT698_MESSAGE_MANAGER_H__
#define __DLT698_MESSAGE_MANAGER_H__

#include <unordered_map>
#include <stdint.h>
#include <mutex>
#include <iostream>
#include <memory>

#include "dlt698_frame.h"
#include "CMosquittoManager.h"
#include "MessagePacket.h"
#include "protocol_engine_config.h"
#include "SerialProxy.h"
#include "global_data_struct.h"
#include "CThreadPool.h"
#include "IModule.h"



class MessageManager{
public:

    
public:
    MessageManager(std::string addr, uint8_t *lc, uint8_t sbc);
    MessageManager();
    ~MessageManager();

    
    int  set_lead_code(uint8_t *lc);
    int  set_scrambling_code(uint8_t sbc);
    int  run(std::shared_ptr<CConfigManager> cm, SerialProxy *sp_ptr, std::shared_ptr<CMosquittoManager> mm, TASK_PARAMS *task_params);
    int  packet_parent_frame(std::shared_ptr<CConfigManager> cm, 
                            IModule &im, 
                            std::shared_ptr<TERMINAL_DEVICE> pdev, 
                            uint8_t *data, int &len);
    static std::shared_ptr<MessageManager> getInstance();
    
private:
    int     c_request_id;
    int     c_max_oad_num;
    int     c_data_len;
    int     c_apdu_len;
    int     c_frame_len;
    int     c_data_max_len;
    bool    c_is_lead_code;

    MessagePacket c_mp;
    uint8_t *c_apdu;
    uint8_t *c_frame;
    uint8_t *c_data;
    std::shared_ptr<CMosquittoManager> c_mm;
    std::shared_ptr<CConfigManager> c_cm;
    SerialProxy *c_sp;
    TASK_PARAMS *c_task_params;
    static std::mutex c_singleton;

    CThreadPool  c_tp;

    void init();
    void init_frame();
    void init_thread_pool();
    
    SEPARATE_FRAME get_sf_flag(uint8_t *apdu, int len);

    int  handle_msg(std::shared_ptr<CConfigManager> cm);
    int  split_joint_data(uint8_t *data, int data_len);
    int  send_confirm(std::shared_ptr<CConfigManager> cm, int req_id);
    int  assemble_and_send_frame(std::shared_ptr<CConfigManager> cm, std::shared_ptr<TERMINAL_DEVICE> dev, TASK_PARAMS *task_params);
    int  get_max_oad_num(std::shared_ptr<CConfigManager> cm);
    void save_send_log(int64_t dev_id, int64_t task_id, char *buf, int len);
    void save_recv_log(int64_t dev_id, int64_t task_id, char *buf, int len);
};






#endif /* __DLT698_MESSAGE_MANAGER_H__ */